from sqlalchemy.exc import SQLAlchemyError

from app import db
from app.models.meal import Meal
from app.models.workout_record import WorkoutRecord
from app.models.meal_foods import MealFood
from app.models.meal_logs import MealLog
from app.models.recipe import Recipe
from app.models.foods import Food
from app.services.food_service import FoodService
from datetime import datetime
from sqlalchemy import func
from deap import base, creator, tools, algorithms
import random


class RecipeService:
    def __init__(self):
        # 初始化一些常量
        self.food_type_categories = {
            '食材': ["主食", "肉蛋", "奶", "蔬果", "零食", "坚果", "豆制品", "其他", "饮料", "素斋", "炖", "烤",
                     "凉拌", "清蒸", "煮"],
            '菜肴': ["饮料", "素斋", "陕西", "炖", "烤", "凉拌", "清蒸", "煮"]
        }



    def get_food_for_diet(self, config):
        """根据用户配置获取食材或菜肴数据"""
        if config['food_type'] == "食材":
            food_categories = self.food_type_categories['食材']
        else:
            # 包含地方菜
            food_categories = [config['local']] + self.food_type_categories['菜肴']

        # 从数据库中查询符合条件的食物
        foods_query = Food.query.filter(Food.category_2.in_(food_categories)).all()
        return foods_query

    def generate_diet_plan(self, config):
        """根据用户的配置生成食谱计划并保存到数据库"""
        # 获取用户的已有食谱
        # 更新食谱标记

        recipe_record = self.get_recipes_by_date(config['user_id'], config['date'])
        # print(recipe_record)
        # 获取符合条件的食物列表
        foods = self.get_food_for_diet(config)
        food_dict = {food.food_id: food for food in foods}
        food_list = list(food_dict.keys())
        # print(food_list)
        # 遗传算法部分（遗传算法配置、适应度函数等）
        best_recipe = self._generate_best_recipe(config, food_dict, food_list)
        best_recipe = self._recipe_format(best_recipe, food_dict, recipe_record, config, is_generated=True)
        best_recipe = adjust_macronutrients2(best_recipe,
                                             config['macro_ratio']['carbohydrate'],
                                             config['macro_ratio']['fat'],
                                             config['macro_ratio']['protein'])
        best_recipe = adjust_calories2(best_recipe,
                                       target_calories=config['total_calories'])
        print(f"best_recipe: {best_recipe['meals']}")
        self._recipe_to_db(best_recipe, config)
        # 将生成的食谱保存到数据库并添加食物

        # recipe_data = self._save_recipe_to_db( best_recipe, food_dict, recipe_record,config, is_generated=True)
        # 返回格式化后的食谱数据
        return best_recipe


    def _recipe_format(self, best_recipe, food_dict, recipe_record, config, is_generated=True):
        """将生成的食谱保存到数据库"""
        # food_service = FoodService()  # 创建 FoodService 实例
        recipe_data = []
        total_day_calories = 0
        total_day_carbs = 0
        total_day_protein = 0
        total_day_fat = 0
        # 遍历新的食谱并与已有的食谱结合
        for meal_index, meal in enumerate(best_recipe):
            # 获取现有的 meal_id
            meal_id = recipe_record['meals'][meal_index]['meal_id']  # 从已有记录中获取meal_id
            meal_data = {
                'meal_id': meal_id,
                "status": recipe_record['meals'][meal_index]['status'],
                "header": recipe_record['meals'][meal_index]['header'],
                'totalCalories': 0,
                'totalCarbs': 0,
                'totalProtein': 0,
                'totalFat': 0,
                'foodList': []
            }
            # 获取餐次中的食物
            for food, quantity in meal:  # 遍历最佳食谱中的每个食物
                food_obj = food_dict.get(food)
                if not food_obj:
                    continue
                food_calories = round(food_obj.calories * quantity, 1)
                food_carbs = round((food_obj.carbohydrate or 0) * quantity, 1)
                food_protein = round((food_obj.protein or 0) * quantity, 1)
                food_fat = round((food_obj.fat or 0) * quantity, 1)
                meal_data['foodList'].append({
                    "description": f"碳{round(quantity * food_carbs, 1)}g|蛋{(round(quantity * food_protein, 1))}g|脂{round(quantity * food_fat, 1)}g",
                    "note": f"{round(quantity * 100, 1)}g\n{round(quantity * food_calories, 1)}kcal",
                    'food_id': food_obj.food_id,
                    'title': food_obj.name,
                    'category_1': food_obj.category_1,
                    'category_2': food_obj.category_2,
                    'calories': round(food_calories, 1),
                    'carbs': round(food_carbs, 1),
                    'protein': round(food_protein, 1),
                    'fat': round(food_fat, 1),
                    'image': (
                        f"/images/foods/{food_obj.img_name}.jpg" if food_obj.img_name else r"/images/groceries.png"),
                    'quantity': quantity
                })
                # 累加每餐的总热量和营养素
                meal_data['totalCalories'] += food_calories
                meal_data['totalCarbs'] += food_carbs
                meal_data['totalProtein'] += food_protein
                meal_data['totalFat'] += food_fat
            # 计算每餐的营养素配比
            meal_data['carbohydrate_ratio'] = (
                round(meal_data['totalCarbs'] * 4 / meal_data['totalCalories'], 1) if meal_data[
                                                                                          'totalCalories'] > 0 else 0)
            meal_data['protein_ratio'] = (
                round(meal_data['totalProtein'] * 4 / meal_data['totalCalories'], 1) if meal_data[
                                                                                            'totalCalories'] > 0 else 0)
            meal_data['fat_ratio'] = (
                round(meal_data['totalFat'] * 9 / meal_data['totalCalories'], 1) if meal_data[
                                                                                        'totalCalories'] > 0 else 0)
            # 累加一天的总热量和营养素
            total_day_calories += meal_data['totalCalories']
            total_day_carbs += meal_data['totalCarbs']
            total_day_protein += meal_data['totalProtein']
            total_day_fat += meal_data['totalFat']

            recipe_data.append(meal_data)
        # 计算一天的总营养素配比
        day_carbohydrate_ratio = (round(total_day_carbs * 4 / total_day_calories, 1) if total_day_calories > 0 else 0)
        day_protein_ratio = (round(total_day_protein * 4 / total_day_calories, 1) if total_day_calories > 0 else 0)
        day_fat_ratio = (round(total_day_fat * 9 / total_day_calories, 1) if total_day_calories > 0 else 0)

        # 添加一天的总信息
        daily_recipe = {
            'total_day_calories': round(total_day_calories, 1),
            'total_day_carbs': round(total_day_carbs, 1),
            'total_day_protein': round(total_day_protein),
            'total_day_fat': round(total_day_fat),
            'carbohydrate_ratio': round(day_carbohydrate_ratio, 1),
            'protein_ratio': round(day_protein_ratio),
            'fat_ratio': round(day_fat_ratio, 1)
        }
        date = config['date']
        user_id = config['user_id']
        date_obj = datetime.strptime(date, '%Y-%m-%d')  # 转换日期格式
        print(f"Querying for user_id = {user_id}, date = {date_obj}")
        # recipe = Recipe.query.filter_by(user_id=user_id, created_at=date_obj).first()
        # 使用 SQLAlchemy 的 func.date() 函数提取日期部分
        recipe = Recipe.query.filter_by(user_id=user_id).filter(func.date(Recipe.created_at) == date_obj.date()).first()
        recipe.is_generated = is_generated
        db.session.commit()
        return {
            'daily_recipe': daily_recipe,
            'meals': recipe_data
        }

    def _recipe_to_db(self, best_recipe, config):
        meals = best_recipe['meals']
        daily_recipe = best_recipe['daily_recipe']
        date_obj = datetime.strptime(config['date'], '%Y-%m-%d').date()  # 转换日期格式
        print(f"Querying for user_id = {config['user_id']}, date = {date_obj}")

        # 查询对应日期的 Recipe
        recipe = Recipe.query.filter_by(user_id=config['user_id']).filter(
            func.date(Recipe.created_at) == date_obj).first()
        if recipe:
            # 更新 Recipe 的营养信息
            recipe.calories = daily_recipe['total_day_calories']
            recipe.carbohydrate = daily_recipe['total_day_carbs']
            recipe.protein = daily_recipe['total_day_protein']
            recipe.fat = daily_recipe['total_day_fat']
        # 创建 meal_id 与 meal_num 的映射
        meal_map = {
            "早餐": 1,
            "午餐": 2,
            "晚餐": 3,
            "零食": 4
        }
        try:
            for meal in meals:
                meal_id = meal['meal_id']
                m = Meal.query.get(meal_id)
                if m:
                    # 更新 Meal 的营养信息
                    m.calories = meal['totalCalories']
                    m.carbohydrate = meal['totalCarbs']
                    m.protein = meal['totalProtein']
                    m.fat = meal['totalFat']
                    # 删除与 meal_id 相关的 MealFood 记录
                    db.session.query(MealFood).filter(MealFood.meal_id == meal_id).delete()
                    # 添加新的食物
                    for food in meal['foodList']:
                        food_id = food['food_id']
                        food_obj = Food.query.get(food_id)

                        if not food_obj or not m:
                            raise ValueError(f"Invalid food_id {food_id} or meal_id {meal_id}")

                        mealNum = meal_map.get(meal['header'], 0)

                        meal_food = MealFood(
                            food_id=food_id,
                            meal_id=meal_id,
                            meal_num=mealNum,
                            quantity=food['quantity'],
                            calories=food['calories']
                        )
                        db.session.add(meal_food)

            # 提交所有的更改
            db.session.commit()

        except SQLAlchemyError as e:
            # 如果发生数据库操作相关的错误，回滚事务
            db.session.rollback()
            print(f"Error occurred while processing user_id {config['user_id']} for date {date_obj}: {str(e)}")
        except Exception as e:
            # 处理其他异常
            db.session.rollback()
            print(f"Unexpected error: {str(e)}")




    def mutate_individual(self, individual, meal_count, meal_food_types, food_list, food_dict, indpb=0.2):
        """自定义变异操作，确保每餐的食物种类要求"""
        for meal in individual:
            if random.random() < indpb:
                # 随机替换一部分食物
                index = random.randint(0, meal_food_types - 1)
                new_food = random.choice(food_list)
                # 确保新食物不与当前餐中的其他食物类别冲突
                categories = {food_dict[food_id].category_2 for food_id in meal}
                if new_food not in meal and food_dict[new_food].category_2 not in categories:
                    meal[index] = new_food
        return (individual,)


    def generate_diet_plan2(self, config):
        """根据用户的配置生成食谱计划"""
        foods = self.get_food_for_diet(config)
        food_dict = {food.food_id: food for food in foods}
        food_list = list(food_dict.keys())

        # 校验是否有足够的食物来满足每餐的食物种类要求
        required_foods = config['meal_count'] * config['meal_food_types']
        if len(food_list) < required_foods:
            raise ValueError("可用的食物数量不足以满足每餐的食物种类要求。")

        # 计算每餐的目标热量
        per_meal_calories = config['total_calories'] / config['meal_count']
        calorie_tolerance = 10  # 每餐热量允许误差±50 kcal

        # 遗传算法相关设置
        # 避免重复创建类型
        if not hasattr(creator, "FitnessMin"):
            creator.create("FitnessMin", base.Fitness, weights=(-0.5, -10.0, -2.0, -2.0, -1.0, -1.0))  #
        if not hasattr(creator, "Individual"):
            creator.create("Individual", list, fitness=creator.FitnessMin)

        toolbox = base.Toolbox()

        def init_individual():
            individual = []
            # 生成每餐的食物
            for _ in range(config['meal_count']):
                # 随机选择 meal_food_types 种食物
                meal = random.sample(food_list, config['meal_food_types'])
                # 生成食物的数量，范围是 1 到 3，步长 0.5
                meal_with_quantity = [(food, round(random.uniform(1, 2) * 2) / 4) for food in meal]
                # 将每餐的食物与份数组合起来
                individual.append(meal_with_quantity)
            return individual

        toolbox.register("individual", tools.initIterate, creator.Individual, init_individual)
        toolbox.register("population", tools.initRepeat, list, toolbox.individual)

        def evaluate(individual):
            """适应度函数，计算总的热量和营养素比例误差"""
            total_error = 0
            total_calories = 0
            total_carbs = 0
            total_protein = 0
            total_fat = 0

            # 权重系数（可调节的参数）
            weight_carbs = 30.0
            weight_protein = 50.0
            weight_fat = 10.0
            weight_calories = 70.0
            weight_categories = 5.0  # 类别约束的惩罚权重

            # 误差分量
            calorie_errors = 0
            carb_errors = 0
            protein_errors = 0
            fat_errors = 0
            category_errors = 0

            for meal in individual:
                meal_calories = 0
                meal_carbs = 0
                meal_protein = 0
                meal_fat = 0
                categories = set()

                for food, quantity in meal:
                    food_obj = food_dict[food]
                    meal_calories += food_obj.calories * quantity # / 100
                    # 假设 Food 模型包含 carbohydrate, protein, fat 字段酶100g包含的克数
                    meal_carbs += (food_obj.carbohydrate or 0) * quantity # * food_obj.calories/ 10000
                    meal_protein += (food_obj.protein or 0) * quantity # * food_obj.calories / 10000
                    meal_fat += (food_obj.fat or 0) * quantity # * food_obj.calories/ 10000
                    categories.add(food_obj.category_2)

                # 热量误差
                calorie_error = abs(meal_calories - per_meal_calories)
                if calorie_error > calorie_tolerance:
                    total_error += (calorie_error - calorie_tolerance)  # 只计算超过部分
                total_calories += meal_calories

                # 营养素比例误差
                target_carbs = per_meal_calories * config['macro_ratio']['carbohydrate']/4 # 每餐碳水重量
                target_protein = per_meal_calories * config['macro_ratio']['protein']/4 # 每餐蛋白质重量
                target_fat = per_meal_calories * config['macro_ratio']['fat']/9 # 每餐脂肪重量

                carb_error = abs(meal_carbs - target_carbs)
                protein_error = abs(meal_protein - target_protein)
                fat_error = abs(meal_fat - target_fat)

                total_error += carb_error + protein_error + fat_error

                # 类别约束
                if len(categories) < config['meal_food_types']:
                    total_error += weight_categories    # 每餐食物来自不同类别

                # 更新总的热量和营养素
                # total_calories += meal_calories
                total_carbs += meal_carbs
                total_protein += meal_protein
                total_fat += meal_fat

                # 计算总误差，考虑误差权重
                total_error = (
                        weight_calories * calorie_errors +
                        weight_carbs * carb_errors +
                        weight_protein * protein_errors +
                        weight_fat * fat_errors +
                        category_errors
                )
                # 返回更多的指标供调试和优化
                return (
                    total_error,  # 总误差
                    calorie_errors,  # 热量误差
                    carb_errors,  # 碳水化合物误差
                    protein_errors,  # 蛋白质误差
                    fat_errors,  # 脂肪误差
                    category_errors  # 类别约束误差
                )


        toolbox.register("mate", tools.cxTwoPoint)  # 交叉操作
        toolbox.register("mutate", self.mutate_individual2, meal_count=config['meal_count'],
                         meal_food_types=config['meal_food_types'], food_list=food_list, food_dict=food_dict)
        toolbox.register("select", tools.selTournament, tournsize=3)  # 选择操作
        toolbox.register("evaluate", evaluate)

        # 创建初始种群
        population = toolbox.population(n=200)

        # 运行遗传算法
        algorithms.eaSimple(population, toolbox, cxpb=0.6, mutpb=0.2, ngen=500, verbose=True)

        # 获取最佳食谱
        best_individual = tools.selBest(population, 1)[0]
        best_recipe = best_individual

        # 构建返回的食谱数据
        recipe_data = []
        total_day_calories = 0
        total_day_carbs = 0
        total_day_protein = 0
        total_day_fat = 0

        for meal in best_recipe:
            meal_data = {
                'meal_calories': 0,  # 每餐的总热量
                'meal_carbs': 0,  # 每餐的碳水化合物总量
                'meal_protein': 0,  # 每餐的蛋白质总量
                'meal_fat': 0,  # 每餐的脂肪总量
                'food_details': []  # 每个食物的详细信息
            }
            for food, quantity in meal:
                food_obj = food_dict[food]
                food_calories = food_obj.calories * quantity #/ 100
                food_carbs = (food_obj.carbohydrate or 0)  * quantity # * food_obj.calories/ 10000
                food_protein = (food_obj.protein or 0) * quantity #* food_obj.calories / 10000
                food_fat = (food_obj.fat or 0)  * quantity #* food_obj.calories/ 10000

                meal_data['food_details'].append({
                    'food_id': food_obj.food_id,
                    'name': food_obj.name,
                    'category_1': food_obj.category_1,
                    'category_2': food_obj.category_2,
                    'calories': food_calories,
                    'carbohydrate': food_carbs,
                    'protein': food_protein,
                    'fat': food_fat,
                    'img_name': food_obj.img_name,
                    'quantity': quantity  # 食物份数
                })

                # 累加每餐的总热量和营养素
                meal_data['meal_calories'] += food_calories
                meal_data['meal_carbs'] += food_carbs
                meal_data['meal_protein'] += food_protein
                meal_data['meal_fat'] += food_fat

            # 计算每餐的营养素配比
            meal_data['carbohydrate_ratio'] = meal_data['meal_carbs']*4 / meal_data['meal_calories'] if meal_data[
                                                                                                          'meal_calories'] > 0 else 0
            meal_data['protein_ratio'] = meal_data['meal_protein']*4 / meal_data['meal_calories'] if meal_data[
                                                                                                       'meal_calories'] > 0 else 0
            meal_data['fat_ratio'] = meal_data['meal_fat']*9 / meal_data['meal_calories'] if meal_data[
                                                                                               'meal_calories'] > 0 else 0

            # 累加一天的总热量和营养素
            total_day_calories += meal_data['meal_calories']
            total_day_carbs += meal_data['meal_carbs']
            total_day_protein += meal_data['meal_protein']
            total_day_fat += meal_data['meal_fat']

            # 添加每餐的详细信息
            recipe_data.append(meal_data)

        # 计算一天的总营养素配比
        day_carbohydrate_ratio = total_day_carbs*4 / total_day_calories if total_day_calories > 0 else 0
        day_protein_ratio = total_day_protein*4 / total_day_calories if total_day_calories > 0 else 0
        day_fat_ratio = total_day_fat*9 / total_day_calories if total_day_calories > 0 else 0

        # 将一天的总信息添加到返回数据中
        # 创建返回的总信息（总的食谱信息部分）

        # 添加一天的总信息
        daily_recipe = {
            'total_day_calories': total_day_calories,
            'total_day_carbs': total_day_carbs,
            'total_day_protein': total_day_protein,
            'total_day_fat': total_day_fat,
            'carbohydrate_ratio': day_carbohydrate_ratio,
            'protein_ratio': day_protein_ratio,
            'fat_ratio': day_fat_ratio
        }
        # 将生成的食谱保存到数据库
        # recipe_data = self._save_recipe_to_db(config, best_recipe)

        # 返回的结构：总信息 + 每餐的详细信息
        return {
            'daily_recipe': daily_recipe,
            'recipe_data': recipe_data
        }



    def mutate_individual2(self, individual, meal_count, meal_food_types, food_list, food_dict, indpb=0.2):
        """自定义变异操作，确保每餐的食物种类要求"""
        for meal in individual:
            if random.random() < indpb:
                # 随机替换一部分食物
                index = random.randint(0, meal_food_types - 1)
                new_food = random.choice(food_list)
                # 随机调整份数
                # new_quantity = random.randint(1, 5)
                new_quantity = random.choice([0.2, 0.5, 0.7, 1.0, 1.2, 1.5, 1.7, 2.0])
                # 确保新食物不与当前餐中的其他食物类别冲突
                categories = {food_dict[food].category_2 for food, _ in meal}
                if new_food not in meal and food_dict[new_food].category_2 not in categories:
                    meal[index] = (new_food, new_quantity)
        return (individual,)



    def _generate_best_recipe(self, config, food_dict, food_list):
        """生成最佳食谱（此处省略遗传算法实现）"""
        # 计算每餐的目标热量
        per_meal_calories = config['total_calories'] / config['meal_count']
        calorie_tolerance = 10  # 每餐热量允许误差±50 kcal
        # 校验是否有足够的食物来满足每餐的食物种类要求
        required_foods = config['meal_count'] * config['meal_food_types']
        if len(food_list) < required_foods:
            raise ValueError("可用的食物数量不足以满足每餐的食物种类要求。")

        # 遗传算法相关设置
        # 避免重复创建类型
        if not hasattr(creator, "FitnessMin"):
            creator.create("FitnessMin", base.Fitness, weights=(-0.5, -10.0, -2.0, -2.0, -1.0, -1.0))  #
        if not hasattr(creator, "Individual"):
            creator.create("Individual", list, fitness=creator.FitnessMin)

        def init_individual():
            individual = []
            # 生成每餐的食物
            for _ in range(config['meal_count']):
                # 随机选择 meal_food_types 种食物
                meal = random.sample(food_list, config['meal_food_types'])
                # 生成食物的数量，范围是 1 到 3，步长 0.5
                meal_with_quantity = [(food, round(random.uniform(1, 2) * 2) / 4) for food in meal]
                # 将每餐的食物与份数组合起来
                individual.append(meal_with_quantity)
            return individual

        def evaluate(individual):
            """适应度函数，计算总的热量和营养素比例误差"""
            total_error = 0
            total_calories = 0
            total_carbs = 0
            total_protein = 0
            total_fat = 0

            # 权重系数（可调节的参数）
            weight_carbs = 30.0
            weight_protein = 30.0
            weight_fat = 10.0
            weight_calories = 70.0
            weight_categories = 5.0  # 类别约束的惩罚权重

            # 误差分量
            calorie_errors = 0
            carb_errors = 0
            protein_errors = 0
            fat_errors = 0
            category_errors = 0

            for meal in individual:
                meal_calories = 0
                meal_carbs = 0
                meal_protein = 0
                meal_fat = 0
                categories = set()

                for food, quantity in meal:
                    food_obj = food_dict[food]
                    meal_calories += food_obj.calories * quantity # / 100
                    # 假设 Food 模型包含 carbohydrate, protein, fat 字段酶100g包含的克数
                    meal_carbs += (food_obj.carbohydrate or 0) * quantity # * food_obj.calories/ 10000
                    meal_protein += (food_obj.protein or 0) * quantity # * food_obj.calories / 10000
                    meal_fat += (food_obj.fat or 0) * quantity # * food_obj.calories/ 10000
                    categories.add(food_obj.category_2)

                # 热量误差
                calorie_error = abs(meal_calories - per_meal_calories)
                if calorie_error > calorie_tolerance:
                    total_error += (calorie_error - calorie_tolerance)  # 只计算超过部分
                total_calories += meal_calories

                # 营养素比例误差
                target_carbs = per_meal_calories * config['macro_ratio']['carbohydrate'] / 4  # 每餐碳水重量
                target_protein = per_meal_calories * config['macro_ratio']['protein'] / 4  # 每餐蛋白质重量
                target_fat = per_meal_calories * config['macro_ratio']['fat'] / 9  # 每餐脂肪重量

                carb_error = abs(meal_carbs - target_carbs)
                protein_error = abs(meal_protein - target_protein)
                fat_error = abs(meal_fat - target_fat)

                total_error += carb_error + protein_error + fat_error

                # 类别约束
                if len(categories) < config['meal_food_types']:
                    total_error += weight_categories  # 每餐食物来自不同类别

                # 更新总的热量和营养素
                # total_calories += meal_calories
                total_carbs += meal_carbs
                total_protein += meal_protein
                total_fat += meal_fat

                # 计算总误差，考虑误差权重
                total_error = (
                        weight_calories * calorie_errors +
                        weight_carbs * carb_errors +
                        weight_protein * protein_errors +
                        weight_fat * fat_errors +
                        category_errors
                )
                # 返回更多的指标供调试和优化
                return (
                    total_error,  # 总误差
                    calorie_errors,  # 热量误差
                    carb_errors,  # 碳水化合物误差
                    protein_errors,  # 蛋白质误差
                    fat_errors,  # 脂肪误差
                    category_errors  # 类别约束误差
                )


        toolbox = base.Toolbox()
        toolbox.register("individual", tools.initIterate, creator.Individual, init_individual)
        toolbox.register("population", tools.initRepeat, list, toolbox.individual)
        toolbox.register("mate", tools.cxTwoPoint)  # 交叉操作
        toolbox.register("mutate", self.mutate_individual2, meal_count=config['meal_count'],
                         meal_food_types=config['meal_food_types'], food_list=food_list, food_dict=food_dict)
        toolbox.register("select", tools.selTournament, tournsize=3)  # 选择操作
        toolbox.register("evaluate", evaluate)

        # 创建初始种群
        population = toolbox.population(n=100)

        # 运行遗传算法
        algorithms.eaSimple(population, toolbox, cxpb=0.6, mutpb=0.2, ngen=300, verbose=True)
        print("initialized")
        # 获取最佳食谱
        best_individual = tools.selBest(population, 1)[0]
        print(best_individual)

        return best_individual



    def _save_recipe_to_db(self, best_recipe, food_dict, recipe_record,config, is_generated=True):
        """将生成的食谱保存到数据库"""

        food_service = FoodService()  # 创建 FoodService 实例

        recipe_data = []
        total_day_calories = 0
        total_day_carbs = 0
        total_day_protein = 0
        total_day_fat = 0

        # 遍历新的食谱并与已有的食谱结合
        for meal_index, meal in enumerate(best_recipe):
            # 获取现有的 meal_id
            meal_id = recipe_record['meals'][meal_index]['meal_id']  # 从已有记录中获取meal_id
            # 查询并删除 MealFood 中所有与该 meal_id 相关的记录
            meal_foods = db.session.query(MealFood).filter(MealFood.meal_id == meal_id).all()
            if meal_foods:
                for meal_food in meal_foods:
                    db.session.delete(meal_food)
                # 提交删除操作
                db.session.commit()

            meal_data = {
                'meal_id': meal_id,
                "status": recipe_record['meals'][meal_index]['status'],
                "header": recipe_record['meals'][meal_index]['header'],
                'totalCalories': 0,
                'totalCarbs': 0,
                'totalProtein': 0,
                'totalFat': 0,
                'foodList': []
            }

            # 获取餐次中的食物
            for food, quantity in meal:  # 遍历最佳食谱中的每个食物
                food_obj = food_dict.get(food)
                if not food_obj:
                    continue

                food_calories = round(food_obj.calories * quantity,1)
                food_carbs = round((food_obj.carbohydrate or 0) * quantity,1)
                food_protein = round((food_obj.protein or 0) * quantity,1)
                food_fat = round((food_obj.fat or 0) * quantity,1)

                meal_data['foodList'].append({
                    "description": f"碳{round(quantity *food_carbs,1)}g|蛋{(round(quantity *food_protein,1))}g|脂{round(quantity *food_fat,1)}g",
                    "note": f"{round(quantity * 100,1)}g\n{round(quantity *food_calories,1)}kcal",
                    'food_id': food_obj.food_id,
                    'title': food_obj.name,
                    'category_1': food_obj.category_1,
                    'category_2': food_obj.category_2,
                    'calories': round(food_calories,1),
                    'carbs': round(food_carbs,1),
                    'protein': round(food_protein,1),
                    'fat': round(food_fat,1),
                    'image': (f"/images/foods/{food_obj.img_name}.jpg" if food_obj.img_name else r"/images/groceries.png"),
                    'quantity': quantity
                })

                # 累加每餐的总热量和营养素
                meal_data['totalCalories'] += food_calories
                meal_data['totalCarbs'] += food_carbs
                meal_data['totalProtein'] += food_protein
                meal_data['totalFat'] += food_fat


                # 将食物添加到餐次
                food_service.add_food_to_meal( meal_id,food_obj.food_id,quantity)

            # 计算每餐的营养素配比
            meal_data['carbohydrate_ratio'] = (
                round(meal_data['totalCarbs'] * 4 / meal_data['totalCalories'],1) if meal_data['totalCalories'] > 0 else 0)
            meal_data['protein_ratio'] = (
                round(meal_data['totalProtein'] * 4 / meal_data['totalCalories'],1) if meal_data['totalCalories'] > 0 else 0)
            meal_data['fat_ratio'] = (
                round(meal_data['totalFat'] * 9 / meal_data['totalCalories'],1) if meal_data['totalCalories'] > 0 else 0)

            # 累加一天的总热量和营养素
            total_day_calories += meal_data['totalCalories']
            total_day_carbs += meal_data['totalCarbs']
            total_day_protein += meal_data['totalProtein']
            total_day_fat += meal_data['totalFat']

            recipe_data.append(meal_data)


        # 计算一天的总营养素配比
        day_carbohydrate_ratio = (round(total_day_carbs * 4 / total_day_calories,1) if total_day_calories > 0 else 0)
        day_protein_ratio = (round(total_day_protein * 4 / total_day_calories,1) if total_day_calories > 0 else 0)
        day_fat_ratio = (round(total_day_fat * 9 / total_day_calories,1) if total_day_calories > 0 else 0)

        # 添加一天的总信息
        daily_recipe = {
            'total_day_calories': round(total_day_calories,1),
            'total_day_carbs': round(total_day_carbs,1),
            'total_day_protein': round(total_day_protein),
            'total_day_fat': round(total_day_fat),
            'carbohydrate_ratio': round(day_carbohydrate_ratio,1),
            'protein_ratio': round(day_protein_ratio),
            'fat_ratio': round(day_fat_ratio,1)
        }

        date = config['date']
        user_id = config['user_id']
        date_obj = datetime.strptime(date, '%Y-%m-%d')  # 转换日期格式
        print(f"Querying for user_id = {user_id}, date = {date_obj}")
        # recipe = Recipe.query.filter_by(user_id=user_id, created_at=date_obj).first()
        # 使用 SQLAlchemy 的 func.date() 函数提取日期部分
        recipe = Recipe.query.filter_by(user_id=user_id).filter(func.date(Recipe.created_at) == date_obj.date()).first()
        recipe.is_generated = is_generated
        db.session.commit()


        return {
            'daily_recipe': daily_recipe,
            'meals': recipe_data
        }



    def _create_workout_record(self, user_id, recipe_id, created_at):
        """创建训练记录（如果当天已经存在则返回现有记录）"""
        try:
            # 获取今天的日期
            today = datetime.today().date()

            # 查询是否已有当天的训练记录
            existing_record = WorkoutRecord.query.filter(
                WorkoutRecord.user_id == user_id,
                db.func.date(WorkoutRecord.created_at) == today
            ).first()

            if existing_record:
                # 如果存在，返回已有记录
                return {
                    "message": "Workout record already exists for today",
                    "data": existing_record.to_dict()
                }, 200

            # 如果不存在当天记录，创建新的训练记录
            workout_record = WorkoutRecord(
                user_id=user_id,
                recipe_id=recipe_id,
                created_at=created_at,
                updated_at=created_at
            )

            # 添加到数据库并提交
            db.session.add(workout_record)
            db.session.commit()

            return {
                "message": "Workout record created successfully",
                "data": workout_record.to_dict()
            }, 201

        except Exception as e:
            # 如果发生异常，回滚事务并返回错误信息
            print(f"Error: {str(e)}")
            db.session.rollback()
            return {"error": str(e)}, 500


    def build_recipe_response(self, recipe):
        """根据查询到的食谱数据，构建前端需要的返回数据格式"""
        meals = []
        meals_query = db.session.query(Meal).filter(Meal.recipe_id == recipe.recipe_id).all()

        for meal in meals_query:  # 遍历食谱中的所有餐次
            meal_data = {
                "meal_id": meal.meal_id,
                "header": meal.header,
                "status": meal.status,
                "totalCalories": meal.calories,
                "totalCarbs": meal.carbohydrate,
                "carbohydrate_ratio": round(meal.carbohydrate*4/meal.calories,1),
                "totalProtein": meal.protein,
                "protein_ratio":round(meal.protein*4/meal.calories,1),
                "totalFat":meal.fat,
                "fat_ratio":round(meal.fat*9/meal.calories,1),
                "foodList": []  # 初始化食物列表
            }
            print(meal_data)
            # 查询MealFood和Food表获取每个餐食的食品
            meal_foods = db.session.query(MealFood).filter(MealFood.meal_id == meal.meal_id).all()

            # 查找该餐次的食物
            for meal_food in meal_foods:  # 遍历餐次中的所有食物
                food = db.session.query(Food).filter(Food.food_id == meal_food.food_id).first()
                if food:
                    food_data = {
                        "food_id": food.food_id,
                        "title": food.name,
                        "description": f"碳{food.carbohydrate}g|蛋{food.protein}g|脂{food.fat}g",
                        "note": f"{meal_food.quantity*100}g\n{meal_food.calories}kcal",
                        "image": '/images/groceries.png',
                        "calories": food.calories,
                        "carbs": food.carbohydrate,
                        "protein": food.protein,
                        "fat": food.fat
                    }
                    meal_data["foodList"].append(food_data)
            meals.append(meal_data)
        return {"meals": meals}

    def get_recipes_by_date(self, user_id, date):
        # 查询食谱是否存在
        date_obj = datetime.strptime(date, '%Y-%m-%d')  # 转换日期格式
        print(f"Querying for user_id = {user_id}, date = {date_obj}")
        # recipe = Recipe.query.filter_by(user_id=user_id, created_at=date_obj).first()
        # 使用 SQLAlchemy 的 func.date() 函数提取日期部分
        recipe = Recipe.query.filter_by(user_id=user_id).filter(func.date(Recipe.created_at) == date_obj.date()).first()
        # func.date(Recipe.created_at) 会从 created_at 中提取日期部分（即去掉时分秒）
        if recipe:
            print(f"Found recipe: {recipe}")
            return self._build_recipe_response(recipe)  # 如果找到食谱，构建并返回响应
        else:
            # 如果食谱不存在，返回新的模板和创建食谱记录
            return self._create_and_return_empty_recipe(user_id, date, date_obj)

    def add_recipes_by_date(self, user_id, date, is_generated=False):
        """
        创建或更新用户的食谱，标记是否为生成的食谱。
        如果当天已有食谱记录，则删除并重新写入，并标记为生成的食谱。
        """
        # 创建一个新的食谱记录
        date_obj = datetime.strptime(date, '%Y-%m-%d')
        # 检查当天是否已存在食谱记录
        existing_recipe = Recipe.query.filter_by(user_id=user_id, created_at=date_obj).first()
        if existing_recipe:
            # 如果存在食谱记录，删除旧记录
            db.session.delete(existing_recipe)
            db.session.commit()

        # 创建一个新的食谱记录
        new_recipe = Recipe(
            user_id=user_id,
            created_at=date_obj,
            is_generated=is_generated,  # 标记为生成的食谱
            # 可以在这里补充更多字段
        )
        db.session.add(new_recipe)
        db.session.commit()

        # 将新创建的 recipe_id 写入 workout_record 表
        workout_record = WorkoutRecord.query.filter_by(user_id=user_id, created_at=date_obj).first()
        if workout_record:
            workout_record.recipe_id = new_recipe.recipe_id
            db.session.commit()

        return new_recipe  # 返回新创建的食谱记录


    def get_all_recipes(self):
        """获取所有食谱"""
        recipes = Recipe.query.all()
        return recipes

    def get_recipe_by_id(self, recipe_id):
        """根据ID获取单个食谱"""
        recipe = Recipe.query.get(recipe_id)
        if not recipe:
            return None
        return recipe

    def create_recipe(self, data):
        """创建新食谱"""
        new_recipe = Recipe(
            name=data['name'],
            description=data['description']
        )
        db.session.add(new_recipe)
        db.session.commit()
        return new_recipe

    def update_recipe(self, recipe_id, data, is_generated=None):
        """更新现有食谱"""
        recipe = Recipe.query.get(recipe_id)
        if not recipe:
            return None
        recipe.name = data.get('name', recipe.name)
        recipe.description = data.get('description', recipe.description)
        # 如果传递了 is_generated，就更新该字段
        if is_generated is not None:
            recipe.is_generated = is_generated
        db.session.commit()
        return recipe

    def delete_recipe(self, recipe_id):
        """删除食谱"""
        recipe = Recipe.query.get(recipe_id)
        if not recipe:
            return None
        # 删除与该食谱相关的餐食和餐食食品记录
        meals = Meal.query.filter_by(recipe_id=recipe_id).all()
        for meal in meals:
            meal_foods = MealFood.query.filter_by(meal_id=meal.meal_id).all()
            for meal_food in meal_foods:
                db.session.delete(meal_food)
            db.session.delete(meal)
        db.session.delete(recipe)
        db.session.commit()
        return recipe


    def _build_recipe_response(self, recipe):
        # 根据查询到的食谱数据，构建前端需要的返回数据格式
        meals = []
        meals_query = db.session.query(Meal).filter(Meal.recipe_id == recipe.recipe_id).all()

        for meal in meals_query:  # 遍历食谱中的所有餐次
            # print(meal)
            meal_data = {
                "meal_id": meal.meal_id,
                "header": meal.header,
                "status": meal.status,
                "totalCalories": round(meal.calories),
                "totalCarbs": round(meal.carbohydrate),
                "carbohydrate_ratio": round(meal.carbohydrate * 4 / (meal.calories+0.1), 1),
                "totalProtein": round(meal.protein),
                "protein_ratio": round(meal.protein * 4 / (meal.calories+0.1), 1),
                "totalFat": round(meal.fat),
                "fat_ratio": round(meal.fat * 9 / (meal.calories+0.1), 1),
                "foodList": []  # 初始化食物列表
            }
            # 查询MealFood和Food表获取每个餐食的食品
            meal_foods = db.session.query(MealFood).filter(MealFood.meal_id == meal.meal_id).all()

            # 查找该餐次的食物
            for meal_food in meal_foods:  # 遍历餐次中的所有食物
                food = db.session.query(Food).filter(Food.food_id == meal_food.food_id).first()
                if food:
                    food_data = {
                        "food_id": food.food_id,
                        "title": food.name,
                        "description": f"碳{round(food.carbohydrate)}g|蛋{round(food.protein)}g|脂{round(food.fat)}g",
                        "note": f"{round(meal_food.quantity*100)}g\n{round(meal_food.calories)}kcal",
                        "image": '/images/groceries.png',
                        "calories": round(food.calories),
                        "carbs": round(food.carbohydrate),
                        "protein": round(food.protein),
                        "fat": round(food.fat)
                    }
                    meal_data["foodList"].append(food_data)
            meals.append(meal_data)
        return {"meals": meals}


    def _create_and_return_empty_recipe(self, user_id, date, date_obj):
        # 获取空模板
        print("not found")
        # template = self._get_empty_recipe_template()
        # 如果没有找到食谱记录，插入新记录
        # 创建食谱记录
        created_date = datetime.strptime(date, '%Y-%m-%d')
        # 创建新的食谱记录
        new_recipe = Recipe(
            name=f"用户{user_id}在{date}的食谱",  # 确保这里有有效的名称
            user_id=user_id,
            calories=0,
            carbohydrate=0,
            protein=0,
            fat=0,
            created_at= created_date,
            updated_at=created_date,
        )
        db.session.add(new_recipe)
        db.session.commit()

        # 创建对应的餐食记录（4个餐食模板：早餐、午餐、晚餐、零食）
        meals_template = [
            {"header": "早餐"},
            {"header": "午餐"},
            {"header": "晚餐"},
            {"header": "零食"}
        ]

        meal_ids = []
        for meal_template in meals_template:
            meal = Meal(
                recipe_id=new_recipe.recipe_id,
                header=meal_template["header"],
                status=0,  # 初始状态
                calories=0,
                carbohydrate=0,
                protein=0,
                fat = 0,
                created_at=date_obj,
                updated_at=date_obj
            )
            db.session.add(meal)
            db.session.commit()
            meal_ids.append(meal.meal_id)

        # 创建用户当天的训练记录
        # workout_record = WorkoutRecord(
        #     user_id=user_id,
        #     recipe_id=new_recipe.recipe_id,
        #     created_at=date_obj,
        #     updated_at=date_obj
        # )
        # db.session.add(workout_record)
        # db.session.commit()
        self._create_workout_record(user_id,new_recipe.recipe_id,created_at=date_obj)

        # 返回初始化的餐食模板
        meals_template_response = [
            {
                "meal_id": str(meal_id),
                "header": meal_template["header"],
                "totalCalories": 0,
                "totalCarbs": 0,
                "carbohydrate_ratio": 0,
                "totalProtein": 0,
                "protein_ratio": 0,
                "totalFat": 0,
                "fat_ratio": 0,
                "status": 0,
                "foodList": []
            } for meal_id, meal_template in zip(meal_ids, meals_template)
        ]

        return {"meals": meals_template_response}

    def _get_empty_recipe_template(self):
        return {
            'meals': [
                {
                    'meal_id': f'{int(datetime.utcnow().timestamp()) + 1}',
                    'header': '早餐',
                    'status': 0,
                    'foodList': []
                },
                {
                    'meal_id': f'{int(datetime.utcnow().timestamp()) + 2}',
                    'header': '午餐',
                    'status': 0,
                    'foodList': []
                },
                {
                    'meal_id': f'{int(datetime.utcnow().timestamp()) + 3}',
                    'header': '晚餐',
                    'status': 0,
                    'foodList': []
                },
                {
                    'meal_id': f'{int(datetime.utcnow().timestamp()) + 4}',
                    'header': '零食',
                    'status': 0,
                    'foodList': []
                }
            ]
        }



def adjust_calories(recipe_dict, target_calories):
    # 提取总日卡路里
    total_day_calories = recipe_dict['daily_recipe']['total_day_calories']
    
    # 计算比例
    ratio = target_calories / total_day_calories
    
    # 调整每一种食物的卡路里
    for meal in recipe_dict['recipe_data']:
        for food in meal['food_details']:
            food['calories'] *= ratio
        
        # 更新每餐的卡路里总数
        meal['meal_calories'] *= ratio
    
    # 更新每日总卡路里
    recipe_dict['daily_recipe']['total_day_calories'] = target_calories
    
    return recipe_dict

def adjust_macronutrients(recipe_dict, target_carb_ratio, target_fat_ratio, target_protein_ratio):
    # 定义每克蛋白质、碳水化合物、脂肪对应的卡路里
    CALORIES_PER_GRAM_CARB = 4
    CALORIES_PER_GRAM_PROTEIN = 4
    CALORIES_PER_GRAM_FAT = 9
    
    # 定义最大迭代次数避免死循环
    MAX_ITERATIONS = 1000
    
    for meal in recipe_dict['recipe_data']:
        iterations = 0
        while iterations < MAX_ITERATIONS:
            # 计算当前餐的总卡路里、碳水化合物、蛋白质、脂肪的总克数
            total_calories = sum(
                food['calories'] for food in meal['food_details']
            )
            total_carbs = sum(food['carbohydrate'] for food in meal['food_details'])
            total_proteins = sum(food['protein'] for food in meal['food_details'])
            total_fats = sum(food['fat'] for food in meal['food_details'])

            # 计算当前餐的碳水化合物、蛋白质、脂肪所占的卡路里比例
            current_carb_ratio = (total_carbs * CALORIES_PER_GRAM_CARB) / total_calories
            current_protein_ratio = (total_proteins * CALORIES_PER_GRAM_PROTEIN) / total_calories
            current_fat_ratio = (total_fats * CALORIES_PER_GRAM_FAT) / total_calories

            # 检查是否已与目标比例相符
            if (abs(current_carb_ratio - target_carb_ratio) < 0.01 and
                abs(current_protein_ratio - target_protein_ratio) < 0.01 and
                abs(current_fat_ratio - target_fat_ratio) < 0.01):
                break

            # 找出碳水化合物、蛋白质和脂肪供能比例最高的食物
            highest_carb = max(
                meal['food_details'], 
                key=lambda x: (x['carbohydrate'] * CALORIES_PER_GRAM_CARB) / x['calories'] if x['calories'] > 0 else 0
            )
            highest_protein = max(
                meal['food_details'], 
                key=lambda x: (x['protein'] * CALORIES_PER_GRAM_PROTEIN) / x['calories'] if x['calories'] > 0 else 0
            )
            highest_fat = max(
                meal['food_details'], 
                key=lambda x: (x['fat'] * CALORIES_PER_GRAM_FAT) / x['calories'] if x['calories'] > 0 else 0
            )

            # 如果碳水化合物比例过高
            if current_carb_ratio > target_carb_ratio:
                highest_carb['carbohydrate'] = max(0, highest_carb['carbohydrate'] - 1)
                highest_carb['calories'] -= CALORIES_PER_GRAM_CARB
                if current_protein_ratio < target_protein_ratio:
                    highest_protein['protein'] += 0.5
                    highest_protein['calories'] += CALORIES_PER_GRAM_PROTEIN * 0.5
                elif current_fat_ratio < target_fat_ratio:
                    highest_fat['fat'] += 0.2
                    highest_fat['calories'] += CALORIES_PER_GRAM_FAT * 0.2

            # 如果蛋白质比例过低
            elif current_protein_ratio < target_protein_ratio:
                highest_protein['protein'] += 0.5
                highest_protein['calories'] += CALORIES_PER_GRAM_PROTEIN * 0.5
                if current_carb_ratio > target_carb_ratio:
                    highest_carb['carbohydrate'] = max(0, highest_carb['carbohydrate'] - 1)
                    highest_carb['calories'] -= CALORIES_PER_GRAM_CARB
                elif current_fat_ratio > target_fat_ratio:
                    highest_fat['fat'] = max(0, highest_fat['fat'] - 0.2)
                    highest_fat['calories'] -= CALORIES_PER_GRAM_FAT * 0.2

            iterations += 1
        
        # 更新餐的卡路里
        meal['meal_calories'] = sum(
            food['calories'] for food in meal['food_details']
        )
    
    # 更新daily_recipe中的数据
    total_day_calories = 0.0
    total_day_carbs = 0.0
    total_day_proteins = 0.0
    total_day_fats = 0.0

    for meal in recipe_dict['recipe_data']:
        total_day_calories += meal['meal_calories']
        total_day_carbs += sum(food['carbohydrate'] for food in meal['food_details'])
        total_day_proteins += sum(food['protein'] for food in meal['food_details'])
        total_day_fats += sum(food['fat'] for food in meal['food_details'])

    recipe_dict['daily_recipe']['total_day_calories'] = total_day_calories
    recipe_dict['daily_recipe']['total_day_carbs'] = total_day_carbs
    recipe_dict['daily_recipe']['total_day_protein'] = total_day_proteins
    recipe_dict['daily_recipe']['total_day_fat'] = total_day_fats
    
    recipe_dict['daily_recipe']['carbohydrate_ratio'] = (total_day_carbs * CALORIES_PER_GRAM_CARB) / total_day_calories
    recipe_dict['daily_recipe']['protein_ratio'] = (total_day_proteins * CALORIES_PER_GRAM_PROTEIN) / total_day_calories
    recipe_dict['daily_recipe']['fat_ratio'] = (total_day_fats * CALORIES_PER_GRAM_FAT) / total_day_calories

    return recipe_dict


def adjust_calories2(recipe_dict, target_calories):
    # 提取总日卡路里
    total_day_calories = recipe_dict['daily_recipe']['total_day_calories']
    
    # 计算比例
    ratio = target_calories / total_day_calories
    
    # 调整每一种食物的卡路里
    for meal in recipe_dict['meals']:
        for food in meal['foodList']:
            food['calories'] *= ratio
            food['carbs'] *= ratio
            food['fat'] *= ratio
            food['protein'] *= ratio
        
        # 更新每餐的卡路里总数
        meal['totalCalories'] *= ratio
        meal['totalCarbs'] *= ratio
        meal['totalFat'] *= ratio
        meal['totalProtein'] *= ratio
    
    # 更新每日总卡路里
    recipe_dict['daily_recipe']['total_day_calories'] = target_calories
    recipe_dict['daily_recipe']['total_day_carbs'] *= ratio
    recipe_dict['daily_recipe']['total_day_fat'] *= ratio
    recipe_dict['daily_recipe']['total_day_protein'] *= ratio
    
    return recipe_dict

def adjust_macronutrients2(recipe_dict, target_carb_ratio, target_fat_ratio, target_protein_ratio):
    # 定义每克蛋白质、碳水化合物、脂肪对应的卡路里
    CALORIES_PER_GRAM_CARB = 4
    CALORIES_PER_GRAM_PROTEIN = 4
    CALORIES_PER_GRAM_FAT = 9
    
    # 定义最大迭代次数避免死循环
    MAX_ITERATIONS = 1000
    
    for meal in recipe_dict['meals']:
        iterations = 0
        while iterations < MAX_ITERATIONS:
            # 计算当前餐的总卡路里、碳水化合物、蛋白质、脂肪的总克数
            total_calories = sum(
                food['calories'] for food in meal['foodList']
            )
            total_carbs = sum(food['carbs'] for food in meal['foodList'])
            total_proteins = sum(food['protein'] for food in meal['foodList'])
            total_fats = sum(food['fat'] for food in meal['foodList'])

            # 计算当前餐的碳水化合物、蛋白质、脂肪所占的卡路里比例
            current_carb_ratio = (total_carbs * CALORIES_PER_GRAM_CARB) / total_calories
            current_protein_ratio = (total_proteins * CALORIES_PER_GRAM_PROTEIN) / total_calories
            current_fat_ratio = (total_fats * CALORIES_PER_GRAM_FAT) / total_calories

            # 检查是否已与目标比例相符
            if (abs(current_carb_ratio - target_carb_ratio) < 0.01 and
                abs(current_protein_ratio - target_protein_ratio) < 0.01 and
                abs(current_fat_ratio - target_fat_ratio) < 0.01):
                break

            # 找出碳水化合物、蛋白质和脂肪供能比例最高的食物
            highest_carb = max(
                meal['foodList'], 
                key=lambda x: (x['carbs'] * CALORIES_PER_GRAM_CARB) / x['calories'] if x['calories'] > 0 else 0
            )
            highest_protein = max(
                meal['foodList'], 
                key=lambda x: (x['protein'] * CALORIES_PER_GRAM_PROTEIN) / x['calories'] if x['calories'] > 0 else 0
            )
            highest_fat = max(
                meal['foodList'], 
                key=lambda x: (x['fat'] * CALORIES_PER_GRAM_FAT) / x['calories'] if x['calories'] > 0 else 0
            )

            # 如果碳水化合物比例过高
            if current_carb_ratio > target_carb_ratio:
                highest_carb['carbs'] = max(0, highest_carb['carbs'] - 1)
                highest_carb['calories'] -= CALORIES_PER_GRAM_CARB
                if current_protein_ratio < target_protein_ratio:
                    highest_protein['protein'] += 0.5
                    highest_protein['calories'] += CALORIES_PER_GRAM_PROTEIN * 0.5
                elif current_fat_ratio < target_fat_ratio:
                    highest_fat['fat'] += 0.2
                    highest_fat['calories'] += CALORIES_PER_GRAM_FAT * 0.2

            # 如果蛋白质比例过低
            elif current_protein_ratio < target_protein_ratio:
                highest_protein['protein'] += 0.5
                highest_protein['calories'] += CALORIES_PER_GRAM_PROTEIN * 0.5
                if current_carb_ratio > target_carb_ratio:
                    highest_carb['carbs'] = max(0, highest_carb['carbs'] - 1)
                    highest_carb['calories'] -= CALORIES_PER_GRAM_CARB
                elif current_fat_ratio > target_fat_ratio:
                    highest_fat['fat'] = max(0, highest_fat['fat'] - 0.2)
                    highest_fat['calories'] -= CALORIES_PER_GRAM_FAT * 0.2

            iterations += 1
        
        # 更新餐的卡路里
        meal['totalCalories'] = sum(
            food['calories'] for food in meal['foodList']
        )
        meal['totalCarbs'] = sum(food['carbs'] for food in meal['foodList'])
        meal['totalFat'] = sum(food['fat'] for food in meal['foodList'])
        meal['totalProtein'] = sum(food['protein'] for food in meal['foodList'])
    
    # 更新daily_recipe中的数据
    total_day_calories = 0.0
    total_day_carbs = 0.0
    total_day_proteins = 0.0
    total_day_fats = 0.0

    for meal in recipe_dict['meals']:
        total_day_calories += meal['totalCalories']
        total_day_carbs += meal['totalCarbs']
        total_day_proteins += meal['totalProtein']
        total_day_fats += meal['totalFat']

    recipe_dict['daily_recipe']['total_day_calories'] = total_day_calories
    recipe_dict['daily_recipe']['total_day_carbs'] = total_day_carbs
    recipe_dict['daily_recipe']['total_day_protein'] = total_day_proteins
    recipe_dict['daily_recipe']['total_day_fat'] = total_day_fats
    
    recipe_dict['daily_recipe']['carbohydrate_ratio'] = (total_day_carbs * CALORIES_PER_GRAM_CARB) / total_day_calories
    recipe_dict['daily_recipe']['protein_ratio'] = (total_day_proteins * CALORIES_PER_GRAM_PROTEIN) / total_day_calories
    recipe_dict['daily_recipe']['fat_ratio'] = (total_day_fats * CALORIES_PER_GRAM_FAT) / total_day_calories

    return recipe_dict